package drds.configuration.db.xml_mapping.sql_execute;

import drds.configuration.db.xml_mapping.configuration.Configuration;
import lombok.Getter;
import lombok.Setter;

import java.lang.reflect.Method;
import java.lang.reflect.ParameterizedType;
import java.lang.reflect.Type;

public class MapperMethodSignature {
    @Getter
    private final String mapperId;
    @Getter
    private final SqlType sqlType;
    @Setter
    @Getter
    private Class<?> mapperInterface;
    @Setter
    @Getter
    private Method method;
    //
    @Setter
    @Getter
    private boolean returnsVoid;
    //
    @Setter
    @Getter
    private boolean returnsBasicType;
    @Setter

    @Getter
    private boolean returnsMap;
    @Setter
    @Getter
    private boolean returnsDto;
    @Setter
    @Getter
    private Class dtoClass = null;
    //
    @Setter
    @Getter
    private boolean returnsList;
    //
    @Setter
    @Getter
    private Class<?> returnType;

    public MapperMethodSignature(Configuration configuration, Class<?> mapperInterface, Method method) {
        this.mapperInterface = mapperInterface;
        this.method = method;
        //
        final String methodName = method.getName();
        Mapper mapper = getMapper(configuration);
        if (mapper == null) {
            throw new RuntimeException("mapper method不存在: " + mapperInterface.getName() + "#" + methodName);
        }
        mapperId = mapper.getId();
        sqlType = mapper.getSqlType();
        //
        Type returnType = ReturnTypeResolver.resolve(method, this);
        if (returnType instanceof Class<?>) {
            this.returnType = (Class<?>) returnType;
        } else if (returnType instanceof ParameterizedType) {
            this.returnType = (Class<?>) ((ParameterizedType) returnType).getRawType();
        } else {
            this.returnType = method.getReturnType();
        }
    }

    private Mapper getMapper(Configuration configuration) {
        String mapperId = getMapperId();
        if (configuration.hasMapper(mapperId)) {
            return configuration.getMapper(mapperId);
        } else {
            return null;
        }
    }

    public String getMapperId() {
        return mapperInterface.getName() + "#" + method.getName();
    }


}
